package org.thirdHero.core.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.thirdHero.core.domain.GdDistance;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
  
public class MapDistance {

    private static double EARTH_RADIUS = 6378.137;

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    public static final String BATCH_URL = "https://restapi.amap.com/v3/batch?key=";

    /**
     * 根据两个位置的经纬度，来计算两地的距离（单位为KM）
     * 参数为String类型
     *
     * @param lat1Str 用户经度
     * @param lng1Str 用户纬度
     * @param lat2Str 商家经度
     * @param lng2Str 商家纬度
     * @return
     */
    public static double getDistance(String lat1Str, String lng1Str, String lat2Str, String lng2Str) {
        Double lat1 = Double.parseDouble(lat1Str);
        Double lng1 = Double.parseDouble(lng1Str);
        Double lat2 = Double.parseDouble(lat2Str);
        Double lng2 = Double.parseDouble(lng2Str);

        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double difference = radLat1 - radLat2;
        double mdifference = rad(lng1) - rad(lng2);
        double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(difference / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(mdifference / 2), 2)));
        distance = distance * EARTH_RADIUS ;
        ;

        return distance;
    }

    /**
     * 获取当前用户一定距离以内的经纬度值
     * 单位米 return minLat
     * 最小经度 minLng
     * 最小纬度 maxLat
     * 最大经度 maxLng
     * 最大纬度 minLat
     */
    public static Map getAround(String latStr, String lngStr, String raidus) {
        Map map = new HashMap();

        Double latitude = Double.parseDouble(latStr);// 传值给经度
        Double longitude = Double.parseDouble(lngStr);// 传值给纬度

        Double degree = (24901 * 1609) / 360.0; // 获取每度
        double raidusMile = Double.parseDouble(raidus);

        Double mpdLng = Double.parseDouble((degree * Math.cos(latitude * (Math.PI / 180)) + "").replace("-", ""));
        Double dpmLng = 1 / mpdLng;
        Double radiusLng = dpmLng * raidusMile;
        //获取最小经度
        Double minLat = longitude - radiusLng;
        // 获取最大经度
        Double maxLat = longitude + radiusLng;

        Double dpmLat = 1 / degree;
        Double radiusLat = dpmLat * raidusMile;
        // 获取最小纬度
        Double minLng = latitude - radiusLat;
        // 获取最大纬度
        Double maxLng = latitude + radiusLat;

        map.put("minLat", minLat + "");
        map.put("maxLat", maxLat + "");
        map.put("minLng", minLng + "");
        map.put("maxLng", maxLng + "");

        return map;
    }

    public static void main(String[] args) {
/*       // ：38.4941610000,106.2366430000
        System.out.println(gdDistance("106.2366430000,38.4941610000","106.2208199501,38.5178428661","02f27a5173f5d03281d331a8b52a9a47"));
        System.out.println(gdDistance("106.2366430000,38.4941610000","106.22118,38.517815","02f27a5173f5d03281d331a8b52a9a47"));
        System.out.println(getDistance("106.2366430000","38.4941610000","106.22118","38.517815"));
      //  38.5106000000,106.2517870000
        System.out.println(gdDistance("106.2517870000,38.5106000000","106.22118,38.517815","02f27a5173f5d03281d331a8b52a9a47"));
        System.out.println(gdDistance("106.2517870000,38.5106000000","106.22118,38.517815","02f27a5173f5d03281d331a8b52a9a47"));
        System.out.println(getDistance("106.2517870000","38.5106000000","106.22118","38.517815"));*/

        List<GdDistance> gdDistances = new ArrayList<>();
        GdDistance gdDistance1 = new GdDistance("38.46355","106.22288","38.485316","106.230563");
        GdDistance gdDistance2 = new GdDistance("38.4941610000","106.2366430000","38.517815","106.22118");
        gdDistances.add(gdDistance1);
        gdDistances.add(gdDistance2);
        batchGdDistance(gdDistances,"1086d7d44331f6d64657a609519492fa");
    }

    /**
     * 高德地图测距
     * @param startLonLat 起始坐标 116.413731,39.979324
     * @param endLonLat  终点坐标  116.417537,39.97722
     * @return
     */
    public static Long gdDistance(String startLonLat, String endLonLat,String key){
        //返回起始地startAddr与目的地endAddr之间的距离，单位：米
        Long result = 0L;
        String queryUrl = "http://restapi.amap.com/v3/distance?key="+key+"&origins="+startLonLat+"&destination="+endLonLat;
        System.out.println(queryUrl);
        JSONObject jo = HttpRequest.sendRequest(queryUrl,HttpRequest.GET);
        JSONArray ja = jo.getJSONArray("results");
        Object obj= JSON.parseObject(ja.getString(0)).get("distance");
        if(obj==null){
            return result;
        }
        result = Long.parseLong(obj.toString());
        return result;
    }

    /**
     * 批量处理距离问题，这里调用的是高德地图进行的处理,如果无法获得位置信息，距离则为0
     * @param gdDistances
     * @param key
     * @return
     */
    public static List<GdDistance> batchGdDistance(List<GdDistance> gdDistances,String key){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("{");
        stringBuilder.append("\"ops\": [");
        for(int i = 0 ;i < gdDistances.size();i++){
            GdDistance gdDistance = gdDistances.get(i);
            stringBuilder.append("{");
            stringBuilder.append("\"url\": \"/v3/distance?key="+key+"&origins="+gdDistance.getLng1()
                    +","+gdDistance.getLan1()+"&destination="+gdDistance.getLng2()+","+gdDistance.getLan2()+"\"");
            if(gdDistances.size()-1>i){
                stringBuilder.append("},");
            }
        }
        stringBuilder.append("}]}");
        String result = HttpRequest.sendPost(BATCH_URL, stringBuilder.toString());
        System.out.println(result);
        JSONArray resultArr = JSONObject.parseArray(result);
        for(int i = 0 ;i < resultArr.size();i++){
            try{
                JSONObject bodyResult = resultArr.getJSONObject(i);
                String distance = bodyResult.getJSONObject("body").getJSONArray("results").getJSONObject(0).getString("distance");
                gdDistances.get(i).setDistance(Long.parseLong(distance));
            }catch (Exception e){
                gdDistances.get(i).setDistance(0);
            }
        }
        System.out.println(gdDistances.toString());

        return gdDistances;
    }


}